#!/usr/bin/python3
#-*- coding:utf-8 -*-

from OpenGL.GL import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.Qt3DCore import *
from PyQt5.Qt3DRender import *
from pygltflib  import *


def prn_obj(self):
        return  '\n'.join(['  --%s:%s' % item for item in self.__dict__.items()])


class OpenGLWidget(QOpenGLWidget):
        def initializeGL(self):
                self.rootEntity = QEntity()
                self.boxEntity = QEntity(self.rootEntity)
                self.gltf=GLTF2.load('WhipperNude.glb')
                self.gltf.convert_buffers(BufferFormat.DATAURI)  # convert buffer URIs to data.
                defaultscene =  self.gltf.scene   
                nodeindexs = self.gltf.scenes[defaultscene].nodes
                for index in nodeindexs:
                        self.parseGLTFNode(self.gltf.nodes[index])
        def paintGL(self):
                pass

        def parseGLTFAccessor(self,index):
                vertices = []
                if index == None:
                        return vertices
                accessor = self.gltf.accessors[index]
                bufferView = self.gltf.bufferViews[accessor.bufferView]
                buffer = self.gltf.buffers[bufferView.buffer]
                data = self.gltf.decode_data_uri(buffer.uri)
                #print(data)
                #print(accessor)
                #print(bufferView)
                # pull each vertex from the binary buffer and convert it into a tuple of python floats
                size = 0
                tag = 'f'
                conv = "<"#几个float几个f,base64转浮点
                if(accessor.componentType==5120):#BYTE
                        byte = 1
                        tag = 'b'
                elif(accessor.componentType==5121):# UNSIGNED_BYTE
                        byte = 1
                        tag = 'B'
                elif(accessor.componentType==5122):# SHORT
                        byte = 2
                        tag = 'h'
                elif(accessor.componentType==5123):# UNSIGNED_SHORT
                        byte = 2
                        tag = 'H'
                elif(accessor.componentType==5125):# UNSIGNED_INT
                        byte = 4
                        tag = 'I'
                elif(accessor.componentType==5126):# FLOAT
                        byte = 4
                        tag = 'f'

                num = 1        
                if accessor.type=='VEC3':
                        num = 3
                elif accessor.type=='VEC2':
                        num = 2
                elif accessor.type=='VEC4':
                        num = 4
                elif accessor.type=='MAT2':
                        num = 4
                elif accessor.type=='MAT3':
                        num = 9
                elif accessor.type=='MAT4':
                        num = 16
                
                for i in range(0,num):
                        size += byte
                        conv += tag

                #print(conv)
                #print(size)

                for i in range(accessor.count):
                        index = bufferView.byteOffset + accessor.byteOffset + i*size  # the location in the buffer of this vertex
                        d = data[index:index+size]  # the vertex data
                        v = struct.unpack(conv, d)   # convert from base64 to three floats
                        vertices.append(v)
                        #print(i, v)
                return vertices
                
        def parseGLTFMesh(self,mesh):
                for primitive in mesh.primitives:
                        print(primitive)
                        attribute = primitive.attributes
                        pt = self.parseGLTFAccessor(primitive.indices)
                        triangles = [i for sub in pt for i in sub]
                        vertices = self.parseGLTFAccessor(attribute.POSITION)
                        normalvertices = self.parseGLTFAccessor(attribute.NORMAL)
                        self.parseGLTFAccessor(attribute.TANGENT)
                        tex0vertices = self.parseGLTFAccessor(attribute.TEXCOORD_0)
                        tex1vertices = self.parseGLTFAccessor(attribute.TEXCOORD_1)
                        self.parseGLTFAccessor(attribute.COLOR_0)
                        self.parseGLTFAccessor(attribute.JOINTS_0)
                        self.parseGLTFAccessor(attribute.WEIGHTS_0)
                        print(triangles)
                        '''
                        print(normalvertices)
                        print(tex0vertices)
                        print(tex1vertices)'''

        def parseGLTFNode(self,node):
                if(node.mesh==None):
                        print(node.name)
                else:
                        self.parseGLTFMesh(self.gltf.meshes[node.mesh])


if __name__ == "__main__":
        app = QApplication([])
        widget = OpenGLWidget()
        widget.setAttribute(Qt.WA_TranslucentBackground, True)
        fmt=QSurfaceFormat()
        fmt.setSamples(8)
        widget.setFormat(fmt)
        widget.show()
        app.exec_()
